package com.robaone.util;

import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Calendar;

/**
 * <pre>   Copyright Mar 21, 2012 Ansel Robateau
         http://www.robaone.com

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

     http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.</pre>
 * @author Ansel
 *
 */

public class JulianDay {
  private int y;
  private int m;
  private int d;

  public JulianDay(Date date) {
    Calendar cal = GregorianCalendar.getInstance();
    cal.setTime(date);
    this.d = cal.get(GregorianCalendar.DAY_OF_MONTH);
    this.m = cal.get(GregorianCalendar.MONTH);
    this.y = cal.get(GregorianCalendar.YEAR);
  }
  public int Value(){
    return this.julian_day();
  }
  public static int DeltaDays(Date date1,Date date2){
    JulianDay day1 = new JulianDay(date1);
    JulianDay day2 = new JulianDay(date2);
    int retval = day1.julian_day() - day2.julian_day();
    if(retval < 0) retval = retval*-1;
    return retval;
  }
  public static String TimeDifference(Date date1,Date date2){
    FAQCalendar start = new FAQCalendar();
    FAQCalendar end = new FAQCalendar();
    start.setTime(date1);
    end.setTime(date2);
    java.util.Calendar cal1 = Calendar.getInstance();
    cal1.setTime(date1);
    Calendar cal2 = Calendar.getInstance();
    cal2.setTime(date2);
    long days = end.getJulianDay() - start.getJulianDay();
    long hours = (end.getJulianHour() - start.getJulianHour()) % 24;
    long minutes = (end.getJulianMinute() - start.getJulianMinute()) % 60;
    long seconds = (end.getJulianSecond() - start.getJulianSecond()) % 60;

    long milliseconds = (cal2.get(Calendar.MILLISECOND) - cal1.get(Calendar.MILLISECOND)) % 1000;
    if(milliseconds < 0) milliseconds += 1000;
    String daystr = "";
    if(days == 1) daystr = days + " day ";
    if(days > 1) daystr = days + " days ";
    String hourstr = "";
    if(hours == 1) hourstr = hours + " hr ";
    if(hours > 1) hourstr = hours + " hrs ";
    String minutestr = "";
    if(minutes == 1) minutestr = minutes + " min ";
    if(minutes > 1) minutestr = minutes + " mins ";
    String secondstr = "";
    if(seconds == 1) secondstr = seconds + " sec ";
    if(seconds > 1) secondstr = seconds + " secs ";
    String millisecondstr = milliseconds + " ms";
    return daystr + hourstr + minutestr + secondstr + millisecondstr;

  }
  protected int julian_day(){
    FAQCalendar cal = new FAQCalendar();
    cal.set(this.y,this.m,this.d);
    return (int)cal.getJulianDay();
  }
  public static java.util.Date IncrementDateByDays(java.sql.Date javaDate,int noOfDays){
    return JulianDay.IncrementDateByDays(new java.util.Date(javaDate.getTime()),noOfDays);
  }
  public static java.util.Date IncrementDateByDays(long javaDate,int noOfDays){
    return JulianDay.IncrementDateByDays(new java.util.Date(javaDate),noOfDays);
  }
  ///////////////////////
  // java.util.Calendar field constants
  // use these constants with the java.util.Calendar.get( fieldConstant ) method.
  // the java.util.Calendar.set( fieldConstant ) method cannot be used in a Javascript application.
  public static java.util.Date IncrementDateByDays(java.util.Date javaDate,int noOfDays){
    int JCAL_YEAR = Calendar.YEAR;
    int JCAL_MONTH = Calendar.MONTH;
    int JCAL_DAY = Calendar.DAY_OF_MONTH;
    int JCAL_24HOUR = Calendar.HOUR_OF_DAY;
    int JCAL_MINUTE = Calendar.MINUTE;
    Calendar javaCal;
    int lengthOfMonth = 0;
    // create a new Calendar object and initialize it to the date
    javaCal = Calendar.getInstance();
    javaCal.setTime(javaDate);

    // get the time and date
    // use java.util.Calendar.get() with corresponding field constants
    int minute = javaCal.get(JCAL_MINUTE);
    int hour = javaCal.get(JCAL_24HOUR);
    int day = javaCal.get(JCAL_DAY);
    int month = javaCal.get(JCAL_MONTH);
    int year = javaCal.get(JCAL_YEAR);

    // increment date and adjust month and year, if required
    day += noOfDays;
    while(1>0) { // we return when date becomes less than length of month
      switch(month) {
         case Calendar.JANUARY:
         case Calendar.MARCH:
         case Calendar.MAY:
         case Calendar.JULY:
         case Calendar.AUGUST:
         case Calendar.OCTOBER:
         case Calendar.DECEMBER: // 31 day months
           lengthOfMonth = 31;
           break;
         case Calendar.APRIL:
         case Calendar.JUNE:
         case Calendar.SEPTEMBER:
         case Calendar.NOVEMBER: // 30 day months
           lengthOfMonth = 30;
           break;
         case Calendar.FEBRUARY: // February
           if (year % 4 == 0) // leap year -- calculation valid until 2099
             lengthOfMonth = 29;
           else
             lengthOfMonth = 28;
           break;
      } // end switch
      if (day > lengthOfMonth) {
        day -= lengthOfMonth;
        if (month < 12) {
          month++;
        } else {
          month = 1;
          year++;
        }
      } else {
        // we are done. Create Date object and return
        javaCal.set(year,month,day,hour,minute);
        return javaCal.getTime(); // getTime() returns a java.util.Date
      }
    } // end while
  } // end incrementDateByDays()
}